package com.almeros.ohos.multitouch.library;

import ohos.app.Context;
import ohos.multimodalinput.event.TouchEvent;

public abstract class BaseGestureDetector {

    protected final Context mContext;
    protected boolean mGestureInProgress;

    protected TouchEvent mPrevEvent;
    protected TouchEvent mCurrEvent;
    
    protected float mCurrPressure;
    protected float mPrevPressure;
    protected long mTimeDelta;
    
    
	/**
	 * This value is the threshold ratio between the previous combined pressure
	 * and the current combined pressure. When pressure decreases rapidly
	 * between events the position values can often be imprecise, as it usually
	 * indicates that the user is in the process of lifting a pointer off of the
	 * device. This value was tuned experimentally.
	 */
    protected static final float PRESSURE_THRESHOLD = 0.67f;

    
    public BaseGestureDetector(Context context) {
    	mContext = context; 	
    }
    
	/**
	 * All gesture detectors need to be called through this method to be able to
	 * detect gestures. This method delegates work to handler methods
	 * (handleStartProgressEvent, handleInProgressEvent) implemented in
	 * extending classes.
	 * 
	 * @param event
	 * @return Click finish
	 */
    public boolean onTouchEvent(TouchEvent event){
    	final int actionCode = event.getAction() & TouchEvent.NONE;
    	if (!mGestureInProgress) {
    		handleStartProgressEvent(actionCode, event);
    	} else {
    		handleInProgressEvent(actionCode, event);
    	}
    	return true;
    }
    
    /**
	 * Called when the current event occurred when NO gesture is in progress
	 * yet. The handling in this implementation may set the gesture in progress
	 * (via mGestureInProgress) or out of progress
	 * @param actionCode
	 * @param event
	 */
    protected abstract void handleStartProgressEvent(int actionCode, TouchEvent event);
    
	/**
	 * Called when the current event occurred when a gesture IS in progress. The
	 * handling in this implementation may set the gesture out of progress (via
	 * mGestureInProgress).
	 * @param actionCode
	 * @param event
	 */
    protected abstract void handleInProgressEvent(int actionCode, TouchEvent event);
    
    
    protected void updateStateByEvent(TouchEvent curr){
    	final TouchEvent prev = mPrevEvent;
    	
    	// Reset mCurrEvent
        if (mCurrEvent != null) {
            mCurrEvent = null;
        }
        mCurrEvent = curr;

        // Delta time
        mTimeDelta = curr.getStartTime() - prev.getStartTime();

        // Pressure
        mCurrPressure = curr.getForce(curr.getIndex());
        mPrevPressure = prev.getForce(prev.getIndex());
    }
    
    protected void resetState() {
        if (mPrevEvent != null) {
            mPrevEvent = null;
        }
        if (mCurrEvent != null) {
            mCurrEvent = null;
        }
        mGestureInProgress = false;
    }


    /**
     * Returns {@code true} if a gesture is currently in progress.
     * @return {@code true} if a gesture is currently in progress, {@code false} otherwise.
     */
    public boolean isInProgress() {
        return mGestureInProgress;
    }

	/**
	 * Return the time difference in milliseconds between the previous accepted
	 * GestureDetector event and the current GestureDetector event.
	 * 
	 * @return Time difference since the last move event in milliseconds.
	 */
	public long getTimeDelta() {
		return mTimeDelta;
	}

	/**
	 * Return the event time of the current GestureDetector event being
	 * processed.
	 * 
	 * @return Current GestureDetector event time in milliseconds.
	 */
	public long getEventTime() {
		return mCurrEvent.getStartTime();
	}
   
}
